package com.xb.chain.netty.server;

import cn.hutool.json.JSONException;
import cn.hutool.json.JSONUtil;
import com.xb.chain.constant.InfoConstant;
import com.xb.chain.entity.ConnectionInfo;
import com.xb.chain.netty.message.entity.Message;
import com.xb.chain.netty.message.handle.MessageHandle;
import com.xb.chain.constant.MessageType;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

/**
 * @author xiaobin
 * @date 2020/2/22 19:10
 * @desc
 */
@Slf4j
public class NodeServerHandle extends SimpleChannelInboundHandler<String> {
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
      log.info("服务端收到信息:" + msg);
        try {
            Message message = JSONUtil.toBean(msg, Message.class);
            MessageHandle.linkedHashSet.put(message);
        } catch (JSONException e) {
            log.error("消息不符合类型，丢弃消息:{}" + msg);
        }
    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        Message<String> message = Message.createMessage(MessageType.STRING_MESSAGE, "欢迎连接" + NodeServerStart.blockChainProperties.getServerIp() + ":" + NodeServerStart.blockChainProperties.getPort() + "节点");
        ctx.channel().writeAndFlush(JSONUtil.toJsonStr(message)+"\r\n");
        String address = ctx.channel().remoteAddress().toString();

        ConnectionInfo connectionInfo = getIPAddress(address);
        InfoConstant.serverChannelGroup.put(connectionInfo, ctx.channel());

        super.handlerAdded(ctx);
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        String address = ctx.channel().remoteAddress().toString();
        ConnectionInfo connectionInfo = getIPAddress(address);

        if (InfoConstant.serverChannelGroup.containsKey(connectionInfo)) {
            InfoConstant.serverChannelGroup.remove(connectionInfo);
        }
        ctx.channel().close();
        super.handlerRemoved(ctx);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        String address = ctx.channel().remoteAddress().toString();
        ConnectionInfo connectionInfo = getIPAddress(address);

        if (InfoConstant.serverChannelGroup.containsKey(connectionInfo)) {
            InfoConstant.serverChannelGroup.remove(connectionInfo);
        }
        ctx.channel().close();
        super.exceptionCaught(ctx, cause);
    }

    // 获取IP地址
    public ConnectionInfo getIPAddress(String address) {
        if (!StringUtils.isBlank(address)) {
            String ip = address.substring(address.indexOf("/") + 1, address.indexOf(":"));
            String port = address.substring(address.indexOf(":") + 1);
            return ConnectionInfo.builder().ip(ip).port(Integer.valueOf(port)).build();
        }
        return null;
    }
}
